/*
 * BinaryTree.h
 *
 *  Created on: 2012-04-19
 *      Author: tony
 */

#ifndef BINARYTREE_H_
#define BINARYTREE_H_

#include <iostream>
#include "Vertex.h"
#include "Edge.h"

namespace graph {

class TreeNode{
public:
	TreeNode();
	TreeNode(const Vertex& v): left(NULL), right(NULL){
		vertex = new Vertex( v );
	}
	TreeNode(const TreeNode& o): left(NULL), right(NULL){
		vertex = new Vertex( *(o.getVData()) );
	}
	~TreeNode();
	TreeNode* getLeft() const { return left; }
	TreeNode* getRight() const { return right; }
	void setLeft( TreeNode* l){ left = l; }
	void setRight( TreeNode* r){ right = r; }
	Vertex* getVData() const { return new Vertex( *vertex ); }
	int getVertex() const { return vertex->getNumber(); }
private:
	TreeNode* left;
	TreeNode* right;
	Vertex* vertex;
};




class Visitor{
public:
	Visitor(){}
	virtual ~Visitor(){}
	virtual void visit(const TreeNode* n) const{}
};




class TreePrinter : public Visitor {
public:
	virtual void visit( const TreeNode* n ) const {
		std::cout << n->getVData()->getNumber();
	}
};



class BinaryTree {
public:
	/*
	 * Constructors and destructor
	 */
	BinaryTree();
	BinaryTree( TreeNode* r );
	BinaryTree( TreeNode* r, const BinaryTree* leftSubtree, const BinaryTree* rightSubtree);
	virtual ~BinaryTree();
	/*
	 * Commands
	 */
	void attachLeft(const BinaryTree* left ){ root->setLeft( left->root ); }
	void attachRight(const BinaryTree* right ){ root->setRight( right->root ); }
	/*
	 * Queries
	 */
	bool isEmpty()const { return (root == NULL); }
	Vertex* getRootData()const { return root->getVData(); }
	/*
	 * Traversals
	 */
	void preorder( Visitor* v ) const {
		preorder( root, v);
	}
	// friend methods
	friend std::ostream& operator <<(std::ostream& out, const BinaryTree& b) {
		b.preorder( new TreePrinter );
		return out;
	}
private:
	TreeNode* root;

	// private recursive traversals
	void preorder( const TreeNode* p, const Visitor* v) const {
		if ( p != NULL ){
			v->visit( p );
			preorder( p->getLeft(), v );
			preorder( p->getRight(), v );
		}
	}
};
} /* namespace graph */
#endif /* BINARYTREE_H_ */
